﻿using Rapid.Utility.Helper;
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

namespace Rapid.Core.Aop
{
    public class ServiceProxy<T> : RealProxy where T : AopTarget
    {
        private T _target;

        public ServiceProxy(T target) : base(typeof(T))
        {
            this._target = target;
        }

        public void PreProceede(IMessage msg)
        {
            _target.PreProceede();
        }

        public void PostProceede(IMessage msg)
        {
            _target.PostProceede();
        }

        public override IMessage Invoke(IMessage msg)
        {
            try
            {
                PreProceede(msg);

                IMethodCallMessage mcm = msg as IMethodCallMessage;
                object[] args = mcm.Args;
                object returnValue = mcm.MethodBase.Invoke(this._target, args);

                return new ReturnMessage(returnValue, args, args.Length, mcm.LogicalCallContext, mcm);
            }
            catch (Exception ex)
            {
                Exception mcmEx = ex.InnerException;
                LogHelper.Error(_target, mcmEx, mcmEx.Message);

                return new ReturnMessage(ex, msg as IMethodCallMessage);
            }
            finally { PostProceede(msg); }
        }
    }
}